import getLastEvent from '../utils/getLastEvent.js'
import getSelector from '../utils/getSelector.js'
import tracker from '../utils/tracker.js'
export function injectJsError() {
  // 监听全局未捕获的错误 
  window.addEventListener('error', (event) => {
    let lastEvent = getLastEvent() // 获取最后一个交互事件
    // 这是一个脚本加载错误
    if (event.target && (event.target.src || event.target.href)) {
      let log = {
        kind: 'stability', // 监控指标的大类
        type: 'error', // 小类型错误
        errorType: 'resourceError', // JS或者CS资源加载错误
        filename: event.target.src || event.target.href, // 哪个文件报错了
        tagName: event.target.tagName, // 错误所在标签
        // stack: getLines(event.error.stack), // 错误堆栈
        selector: getSelector(event.target) // 代表最后一个操作的元素
      }
      tracker.send(log)  // 上报数据
    } else {
      // 获取冒泡向上的dom路径
      var path = lastEvent.path || (function (evt) {
        var path = [];
        var el = evt.target;
        while (el) {
          path.push(el);
          el = el.parentElement;
        }
        return path;
      })(lastEvent);
      let log = {
        kind: 'stability', // 监控指标的大类
        type: 'error', // 小类型错误
        errorType: 'jsError', // JS执行错误
        filename: event.filename, // 错误所在的文件
        position: event.lineno + ':' + event.colno, // 错误所在的行和列的位置
        message: event.message, // 错误信息
        stack: getLines(event.error.stack), // 错误堆栈
        selector: lastEvent ? getSelector(path) : "" // 代表最后一个操作的元素
      }
      tracker.send(log)  // 上报数据
    }

  }, true)

  window.addEventListener('unhandledrejection', function (event) {
    // console.log("异常错误", event);
    let lastEvent = getLastEvent(); // 最后一个事件对象
    var path = lastEvent.path || (function (evt) {
      var path = [];
      var el = evt.target;
      while (el) {
        path.push(el);
        el = el.parentElement;
      }
      return path;
    })(lastEvent);
    let message;
    let filename;
    let line = 0;
    let column = 0;
    let stack = '';
    let reason = event.reason;
    if (typeof reason === 'string') {
      message = reason;
    } else if (typeof reason === 'object') {  // 说明是一个错误对象 
      if (reason.stack) {
        let matchResult = reason.stack.match(/at\s+(.+):(\d+):(\d+)/);
        filename = matchResult[1];
        line = matchResult[2];
        column = matchResult[3];
      }
      stack = getLines(reason.stack)
    }
    message = reason.message;
    tracker.send({
      kind: 'stability', // 监控指标的大类
      type: 'error', // 小类型错误
      errorType: 'PromiseError', // JS执行错误
      filename, // 错误所在的文件
      position: line + ':' + column, // 错误所在的行和列的位置
      message, // 错误信息
      stack, // 错误堆栈
      selector: lastEvent ? getSelector(path) : "" // 代表最后一个操作的元素
    })  // 上报数据
  }, true)
  // 拼接at报错方法一“^”拼接
  function getLines(stack) {
    return stack.split('\n').map(item => item.replace(/^\s+at\s+/g, '')).join('^');
  }
}